package com.zycfc.zsf.boot.mq.rabbitmq.autoconfigure;

import org.springframework.amqp.rabbit.core.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.amqp.*;
import org.springframework.boot.context.properties.*;
import org.springframework.amqp.core.*;
import org.springframework.core.env.*;
import org.springframework.beans.factory.annotation.*;
import com.zycfc.zsf.boot.mq.common.*;
import javax.annotation.*;
import org.springframework.beans.factory.*;
import org.springframework.amqp.rabbit.listener.*;
import javax.sql.*;
import com.zycfc.zsf.boot.mq.rabbitmq.handler.*;
import org.springframework.context.annotation.*;
import org.springframework.boot.autoconfigure.condition.*;
import com.zycfc.zsf.boot.mq.rabbitmq.producer.*;
import com.zycfc.zsf.boot.util.text.*;
import java.util.*;
import com.zycfc.zsf.boot.core.common.*;
import org.slf4j.*;

@Configuration
@ConditionalOnBean({ RabbitTemplate.class })
@AutoConfigureAfter({ RabbitAutoConfiguration.class })
@EnableConfigurationProperties({ MQProperties.class })
@ConditionalOnProperty(value = { "zsf.boot.mq.enabled" }, matchIfMissing = true)
public class ZsfRabbitMQConfiguration
{
    private static final Logger log;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private AmqpAdmin amqpAdmin;
    private final Environment env;
    private final MessageProducerCallback messageProducerCallback;
    @Value("${zsf.all.namespace:dev}")
    private String namespace;
    private String applicationName;
    @Value("${spring.profiles.active:local}")
    String profilesActive;
    @Autowired
    private MQProperties properties;
    
    @PostConstruct
    public void init() {
        MqEnvConstants.build(this.namespace, this.applicationName, this.getErrNotifyUrl());
    }
    
    public ZsfRabbitMQConfiguration(final ObjectProvider<MessageProducerCallback> messageProducerCallbackHelperProvider, final ObjectProvider<SimpleMessageListenerContainer[]> listenerContainer, final Environment env) throws Exception {
        if (null != messageProducerCallbackHelperProvider) {
            this.messageProducerCallback = (MessageProducerCallback)messageProducerCallbackHelperProvider.getIfAvailable();
        }
        else {
            this.messageProducerCallback = null;
        }
        this.applicationName = env.getProperty("spring.application.name");
        final String envVal = env.getProperty("zsf.all.namespace");
        this.env = env;
        if (null != listenerContainer) {
            final SimpleMessageListenerContainer[] containers = (SimpleMessageListenerContainer[])listenerContainer.getIfAvailable();
            if (null != containers) {
                this.setApplicationName(containers, this.applicationName, envVal);
            }
        }
    }
    
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnClass({ DataSource.class })
    public DbProcessProvider dbProcessProvider(final DataSource dataSource) {
        return new DbProcessProvider(dataSource, this.properties.isInitSqlFlag(), this.profilesActive);
    }
    
    @Bean
    public SimpleMessageProducer simpleMessageProducer(final DbProcessProvider dbProcessProvider) {
        final String applicationName = this.env.getProperty("spring.application.name");
        final SimpleMessageProducer producer = new SimpleMessageProducer(this.rabbitTemplate, this.amqpAdmin, this.namespace, dbProcessProvider);
        producer.setCallback(this.messageProducerCallback);
        if (null != applicationName && !applicationName.trim().isEmpty()) {
            producer.setAppName(applicationName);
        }
        ZsfRabbitMQConfiguration.log.debug("^_^RabbitMQ\u7ec4\u4ef6\u52a0\u8f7d\u6210\u529f^_^");
        return producer;
    }
    
    private void setApplicationName(final SimpleMessageListenerContainer[] containers, final String applicationName, String envVal) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        if (null == applicationName || applicationName.trim().isEmpty()) {
            return;
        }
        for (final SimpleMessageListenerContainer container : containers) {
            final Map<String, Object> args = new HashMap<String, Object>();
            args.put("applicationName", applicationName);
            envVal = (StringUtils.isEmpty(envVal) ? "-" : envVal);
            args.put("env", envVal);
            container.setConsumerArguments((Map)args);
        }
    }
    
    public String getErrNotifyUrl() {
        if (!this.properties.isErrNotifyEnabled()) {
            return null;
        }
        String url = this.properties.getErrNotifyUrl();
        if (!StringUtils.isEmpty(url)) {
            return url;
        }
        url = EnvChangingConstant.MGS_URL.get(this.profilesActive);
        if (StringUtils.isEmpty(url)) {
            url = EnvChangingConstant.MGS_URL.get("default");
        }
        ZsfRabbitMQConfiguration.log.info("active=" + this.profilesActive + ",url=" + url);
        return url;
    }
    
    static {
        log = LoggerFactory.getLogger((Class)ZsfRabbitMQConfiguration.class);
    }
}
